<?php

declare(strict_types=1);

namespace App\CustHub\Service;

use App\CustHub\Event\RobotInfoChange;
use App\CustHub\Mapper\ChRobotMapper;
use App\CustHub\Model\ChMaterial;
use App\CustHub\Model\ChRobot;
use Hyperf\Di\Annotation\Inject;
use Psr\EventDispatcher\EventDispatcherInterface;

abstract class AbstractNotifyService
{
    #[Inject]
    protected ChRobotMapper $robotMapper;

    #[Inject]
    protected EventDispatcherInterface $eventDispatcher;

    protected const ADD_KEY = 'robot_add_key:';


    protected function getAddFriendKey(array $data): string
    {
        return self::ADD_KEY. md5($data['sender'].$data['receiver']);
    }

    protected function checkAddFriendKey(array $data): bool
    {
        return redis()->exists($this->getAddFriendKey($data)) > 0;
    }


    protected function isRoomNotificationProcessed(mixed $from_room_id): bool
    {
        $r= redis()->exists('processed_room_notification:' . $from_room_id);
        return $r > 0;
    }

    protected function markRoomNotificationAsProcessed(mixed $from_room_id): void
    {
        redis()->set('processed_room_notification:' . $from_room_id, $from_room_id,5);
    }


    protected function handleSystemNotification(array $data,ChRobot $robotInfo)
    {
        if($data['msg_type'] == 2115){
            container()->get(RoomReceiveCallBackService::class)->manageLocalContacts($robotInfo);
        }elseif ($data['msg_type'] == 2114){
            //企微号信息变更
            event(new RobotInfoChange($robotInfo));
        }else{
            container()->get(ContactReceiveCallBackService::class)->handle($data,$robotInfo);
        }
    }

    /**
     * 保存视频号素材
     * @param ChRobot $robotInfo
     * @param array $msgData
     * @param int $isPersonal
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function saveVideoChannel(ChRobot $robotInfo,array $msgData,int $isPersonal): void
    {
        $msgData['username'] = base64_decode($msgData['username']);
        $msgData['channel_name'] = base64_decode($msgData['channel_name']);
        $data = [
            'title' => '未命名素材',
            'content' =>  [
                [
                    'msg_type' => 'video_channel',
                    'content' => $msgData,
                    'extra' => []
                ]
            ],
            'is_personal' => $isPersonal
        ];
        ChMaterial::saveMaterial($robotInfo->uid,$robotInfo->main_uid,$data);
    }

    /**
     * 保存小程序素材
     * @param ChRobot $robotInfo
     * @param array $msgData
     * @param int $isPersonal
     * @return void
     * @throws \Psr\Container\ContainerExceptionInterface
     * @throws \Psr\Container\NotFoundExceptionInterface
     */
    protected function saveMiniProgram(ChRobot $robotInfo,array $msgData,int $isPersonal): void
    {
        $msgData['title'] = base64_decode($msgData['title']);
        $msgData['desc'] = base64_decode($msgData['desc']);
        $data = [
            'title' => '未命名素材',
            'content' =>  [
                [
                    'msg_type' => 'mini_program',
                    'content' => $msgData,
                    'extra' => []
                ]
            ],
            'is_personal' => $isPersonal
        ];
        ChMaterial::saveMaterial($robotInfo->uid,$robotInfo->main_uid,$data);
    }

    /**
     * 解析文本消息，提取 @ 昵称并转换为数组
     * @param string $content
     * @param array $atList
     * @return array[]
     */
    public function parseContent(string $content, array $atList): array {
        $items = [];
        $pos = 0; // 当前处理位置
        $contentLength = strlen($content);

        // 依次处理每个 at_list 中的 nickname
        foreach ($atList as $at) {
            $nickname = $at['nickname'];
            $atTag = '@' . $nickname;

            // 以 @nickname 作为分割点来查找匹配的内容
            $startPos = strpos($content, $atTag, $pos);
            if ($startPos === false) {
                continue; // 如果没找到，继续下一个
            }

            // 处理 @nickname 之前的文本
            if ($startPos > $pos) {
                $items[] = [
                    'text' => substr($content, $pos, $startPos - $pos),
                    'type' => 'text'
                ];
            }

            // 添加 @nickname 的结构化对象
            $items[] = [
                'at_id' => $at['user_id'],
                'at_name' => $nickname,
                'text' => '',
                'type' => '@'
            ];

            // 更新处理位置，跳过当前的 @nickname
            $pos = $startPos + strlen($atTag);
        }

        // 处理所有 @ 标签之后的剩余文本
        if ($pos < $contentLength) {
            $items[] = [
                'text' => substr($content, $pos),
                'type' => 'text'
            ];
        }

        return $items;
    }
}